<?php
/**
 * Created by PhpStorm.
 * User: Orange
 * Date: 2018/5/3
 * Time: 14:09
 */

namespace app\admin\logic;


use think\Db;
use think\Exception;
use PHPExcel_Cell;
use PHPExcel_IOFactory;

class CategoryLogic
{
    /**
     * 7个类别导入
     * @param $filename string 文件名
     * @param string $encode
     * @return array
     */
    public function import($filename, $encode = 'utf-8')
    {
        Db::startTrans();
        if (empty($filename)) {
            return array('status' => 2, 'msg' => '请上传Excel文件');
        }
        ini_set("memory_limit", "255M");
        try {
            setlocale(LC_ALL, 'zh_CN');
            $objReader = PHPExcel_IOFactory::createReader('Excel5');//读取xls
            if (!$objReader->canRead($filename)) {
                //读取xlsx
                $objReader = PHPExcel_IOFactory::createReader('Excel2007');
                if (!$objReader->canRead($filename)) {
                    return array('status' => 2, 'msg' => '无法读取文件');
                }
            }
            $objPHPExcel = $objReader->load($filename);
            $objWorksheet = $objPHPExcel->getActiveSheet();
            $highestRow = $objWorksheet->getHighestRow();
            $highestColumn = $objWorksheet->getHighestColumn();
            $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
            $excelData = [];
            for ($row = 2; $row <= $highestRow; $row++) {
//                $value = (string)$objWorksheet->getCellByColumnAndRow(0, $row)->getValue();
//                if ($value == '') {
//                    continue;
//                }
                $excelData[$row] = [];
                for ($col = 0; $col < $highestColumnIndex; $col++) {
                    $value = (string)$objWorksheet->getCellByColumnAndRow($col, $row)->getValue();
                    if (!is_numeric($value) && $value != '') {
                        $value = mb_convert_encoding($value, 'utf-8');
                    }
                    $excelData[$row][] = $value;
                }

                $result = $this->checkData($excelData[$row], $row, 0);
                if ($result['status'] == 0) {
                    Db::rollback();
                    return $result;
                }

                if ($row % 1000 == 0) {
                    $result = $this->executeImport($excelData, 0);
                    if ($result['status'] == 0) {
                        Db::rollback();
                        return $result;
                    }
                }
            }

            if (count($excelData) > 0) {
                $result = $this->executeImport($excelData, 0);
                if ($result['status'] == 0) {
                    Db::rollback();
                    return $result;
                }
            }
            //导入成功
            Db::commit();
            return array('status' => 1);
        } catch (Exception $e) {
            Db::rollback();
            return array('status' => 0, 'msg' => '服务器错误，' . $e->getMessage());
        }
    }

    /**
     * 针对单个类别导入
     * @param $filename
     * @param $category_id
     * @return array
     */
    public function importWithCategoryId($filename, $category_id)
    {
        if (empty($category_id)) {
            return array('status' => 2, 'msg' => $category_id);
        }
        $count = model('Category')->where(array('is_delete' => 0))->count();
        if ($count == 0) {
            return array('status' => 2, 'msg' => '分类不存在');
        }

        if (empty($filename)) {
            return array('status' => 2, 'msg' => '请上传Excel文件');
        }

        ini_set("memory_limit", "255M");
        try {
            setlocale(LC_ALL, 'zh_CN');
            $objReader = PHPExcel_IOFactory::createReader('Excel5');//读取xls
            if (!$objReader->canRead($filename)) {
                //读取xlsx
                $objReader = PHPExcel_IOFactory::createReader('Excel2007');
                if (!$objReader->canRead($filename)) {
                    return array('status' => 2, 'msg' => '无法读取文件');
                }
            }
            $objPHPExcel = $objReader->load($filename);
            $objWorksheet = $objPHPExcel->getActiveSheet();
            $highestRow = $objWorksheet->getHighestRow();
            $highestColumn = $objWorksheet->getHighestColumn();
            $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
            $excelData = [];
            for ($row = 2; $row <= $highestRow; $row++) {
//                $value = (string)$objWorksheet->getCellByColumnAndRow(0, $row)->getValue();
//                if ($value == '') {
//                    continue;
//                }
                $excelData[$row] = [];
                for ($col = 0; $col < $highestColumnIndex; $col++) {
                    $value = (string)$objWorksheet->getCellByColumnAndRow($col, $row)->getValue();
                    if (!is_numeric($value) && $value != '') {
                        $value = mb_convert_encoding($value, 'utf-8');
                    }
                    $excelData[$row][] = $value;
                }

                $result = $this->checkData($excelData[$row], $row, $category_id);
                if ($result['status'] == 0) {
                    return $result;
                }

                if ($row % 1000 == 0) {
                    $result = $this->executeImport($excelData, $category_id);
                    if ($result['status'] == 0) {
                        return $result;
                    }
                }
            }

            if (count($excelData) > 0) {
                $result = $this->executeImport($excelData, $category_id);
                if ($result['status'] == 0) {
                    return $result;
                }
            }
            //导入成功
            return array('status' => 1);
        } catch (Exception $e) {
            return array('status' => 0, 'msg' => '服务器错误，' . $e->getMessage());
        }
    }

    /**
     * 执行导入
     * @param $excelData
     * @param $category_id
     * @return array
     */
    private function executeImport(&$excelData, $category_id)
    {
        $result = $this->importData($excelData, $category_id);
        $excelData = null;
        $excelData = [];
        return $result;
    }

    /**
     * 导入数据
     * 根据category_id判断是单个导入还是7个导入
     * @param $excelData
     * @param $category_id
     * @return array
     */
    private function importData($excelData, $category_id)
    {
        if ($category_id) {
            try {
                foreach ($excelData as $key => $row) {
                    $current_row = $key;
                    $category['name'] = $row[0];
                    $category['english_name'] = $row[1];
                    $category['name'] = str_replace('）',')',$category['name'] );
                    $category['name'] = str_replace(' （','(',$category['name'] );
                    $level = model('Category')->where(array('id' => $category_id)) ->value("current_level");
                    $category_obj = model('Category')->where(array('name' => $category['name'], 'current_level' => $level + 1))->where(array('is_delete' => 0))->find();
                    if (!$category_obj) {
                        $category['parent_id'] = $category_id;
                        $category['current_level'] = $level + 1;
                        model('Category')->create($category);
                    }
                }
                return array('status' => 1);
            } catch (Exception $e) {
                return array('status' => 0, 'msg' => "导入第{$current_row}行数据失败，请检查数据格式是否正确 " . $e->getMessage());
            }
        } else {
            try {
                foreach ($excelData as $key => $row) {
                    $current_row = $key;
                    $category['name'] = $row[0];
                    $category['english_name'] = $row[1];
                    $category['name'] = str_replace('）',')',$category['name'] );
                    $category['name'] = str_replace(' （','(',$category['name'] );
                    $category_obj = model('Category')->where(array('name' => $category['name'], 'current_level' => 0))->where(array('is_delete' => 0))->find();
                    if (!$category_obj) {
                        $category['current_level'] = 0;
                        $category['parent_id'] = 0;
                        $category_obj = model('Category')->create($category);
                        $category_ids[0] = $category_obj['id'];
                    } else {
                        $category_ids[0] = $category_obj['id'];
                    }
                    for ($level = 1, $i = 2; $level < 7; $level++) {
                        $category['name'] = $row[$i];
                        $category['english_name'] = $row[$i + 1];
                        $category['name'] = str_replace('）',')',$category['name'] );
                        $category['name'] = str_replace(' （','(',$category['name'] );
                        $category_obj = model('Category')->where(array('name' => $category['name'], 'current_level' => $level))->where(array('is_delete' => 0))->find();
                        if (!$category_obj) {
                            $category['current_level'] = $level;
                            $category['parent_id'] = $category_ids[$level - 1];
                            $category_obj = model('Category')->create($category);
                            $category_ids[$level] = $category_obj['id'];
                        } else {
                            if ($category_obj['parent_id'] != $category_ids[$level - 1]) {
                                throw new Exception("不能修改{$category_obj['name']}的上级类别");
                            }
                            $category_ids[$level] = $category_obj['id'];
                        }
                        $i = $i + 2;
                    }
                }
                return array('status' => 1);
            } catch (Exception $e) {
                return array('status' => 0, 'msg' => "导入第{$current_row}行数据失败，请检查数据格式是否正确 " . $e->getMessage());
            }
        }
    }

    private function checkData($row_value, $current_row, $category_id)
    {
        $msg = '';
        $result = array('status' => 1, 'msg' => '');
        if ($category_id) {
            if (count($row_value) != 2) {
                $result['status'] = 0;
                $result['msg'] = "导入第{$current_row}行数据失败，该行数据不完整";
                return $result;
            }
            $this->checkWithCategoryId($row_value, $msg, $result);
        } else {
            if (count($row_value) != 14) {
                $result['status'] = 0;
                $result['msg'] = "导入第{$current_row}行数据失败，该行数据不完整";
                return $result;
            }
            $this->checkNull($row_value, $msg, $result);
        }
        if ($result['status'] == 0) {
            $result['msg'] = "导入第{$current_row}行数据失败，" . $msg;
            return $result;
        }
        if ($result['status'] == 0) {
            $result['msg'] = "导入第{$current_row}行数据失败，" . $msg;
        }
        return $result;
    }

    private function checkNull($row_value, &$msg, &$result)
    {
        if ($row_value[0] == '') {
            $result['status'] = 0;
            $msg .= '界类别中文名不能为空';
        }
        if (substr($row_value[0], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '界类别中文名格式错误';
        }
        if ($row_value[1] == '') {//界类别英文名
            $result['status'] = 0;
            $msg .= '界类别英文名不能为空';
        }
        if (substr($row_value[1], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '界类别英文名格式错误';
        }
        if ($row_value[2] == '') {//门类别中文名
            $result['status'] = 0;
            $msg .= '门类别中文名不能为空';
        }
        if (substr($row_value[2], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '门类别中文名格式错误';
        }
        if ($row_value[3] == '') {//门类别英文名
            $result['status'] = 0;
            $msg .= '门类别英文名不能为空';
        }
        if (substr($row_value[3], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '门类别英文名格式错误';
        }
        if ($row_value[4] == '') {//纲类别中文名
            $result['status'] = 0;
            $msg .= '纲类别中文名不能为空';
        }
        if (substr($row_value[4], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '纲类别中文名格式错误';
        }
        if ($row_value[5] == '') {//纲类别英文名
            $result['status'] = 0;
            $msg .= '纲类别英文名不能为空';
        }
        if (substr($row_value[5], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '纲类别英文名格式错误';
        }
        if ($row_value[6] == '') {//目类别中文名
            $result['status'] = 0;
            $msg .= '目类别中文名不能为空';
        }
        if (substr($row_value[6], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '目类别中文名格式错误';
        }
        if ($row_value[7] == '') {//目类别英文名
            $result['status'] = 0;
            $msg .= '目类别英文名不能为空';
        }
        if (substr($row_value[7], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '目类别英文名格式错误';
        }
        if ($row_value[8] == '') {//科类别中文名
            $result['status'] = 0;
            $msg .= '科类别中文名不能为空';
        }
        if (substr($row_value[8], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '科类别中文名格式错误';
        }
        if ($row_value[9] == '') {//科类别英文名
            $result['status'] = 0;
            $msg .= '科类别英文名不能为空';
        }
        if (substr($row_value[9], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '科类别英文名格式错误';
        }
        if ($row_value[10] == '') {//属类别中文名
            $result['status'] = 0;
            $msg .= '属类别中文名不能为空';
        }
        if (substr($row_value[10], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '属类别中文名格式错误';
        }
        if ($row_value[11] == '') {//属类别英文名
            $result['status'] = 0;
            $msg .= '属类别英文名不能为空';
        }
        if (substr($row_value[11], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '属类别英文名格式错误';
        }
        if ($row_value[12] == '') {//种类别中文名
            $result['status'] = 0;
            $msg .= '种类别中文名不能为空';
        }
        if (substr($row_value[12], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '种类别中文名格式错误';
        }
        if ($row_value[13] == '') {//种类别英文名
            $result['status'] = 0;
            $msg .= '种类别英文名不能为空';
        }
        if (substr($row_value[13], 0, 1) == " ") {
            $result['status'] = 0;
            $msg .= '种类别英文名格式错误';
        }
    }

    /**
     * 针对单个类别导入的表格空判断
     * @param $row_value
     * @param $msg
     * @param $result
     */
    private function checkWithCategoryId($row_value, &$msg, &$result)
    {
        if ($row_value[0] == '') {
            $result['status'] = 0;
            $msg .= '下级类别中文名不能为空';
        }
        if ($row_value[1] == '') {//界下级类别英文名英文名
            $result['status'] = 0;
            $msg .= '下级类别英文名不能为空';
        }
    }
}